using System;
using System.IO;

using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;

using Actions.Databases;
using Actions.Security;

namespace Actions
{
	/// <summary>
	/// Document is a alias to XmlDocument
	/// </summary>
	public class Document : XmlDocument
	{	
		private XPathNavigator				_navigator;
		private XmlNamespaceManager			_namespaces;
		
		private string						_xslName = "standart";
		private bool						_mustBeTransformed;
		
		public bool							mustBeTransformed
		{
			get
			{
				return _mustBeTransformed;
			}
			set
			{
				_mustBeTransformed = value;
			}
		}
		public string						xslName
		{
			get
			{
				return _xslName;
			}
			set
			{
				_xslName = value;
			}
		}
		
		public Document() : base()
		{
			InnerXml = "<document timestamp='" + DateTime.Now.ToString() + "'></document>";
			_navigator = DocumentElement.CreateNavigator();
			_namespaces = new XmlNamespaceManager(NameTable);
			_mustBeTransformed = true;
			
		}
		
		public Document(string filename) : base()
		{
			this.Load(filename);
			_navigator = DocumentElement.CreateNavigator();
			_namespaces = new XmlNamespaceManager(NameTable);
		}

		public Document(Stream s) : base()
		{
			this.Load(s);
			_navigator = DocumentElement.CreateNavigator();
			_namespaces = new XmlNamespaceManager(NameTable);
		}
	
		public Document(XPathNavigator n) : base()
		{
			_navigator = n;
			_namespaces = new XmlNamespaceManager(n.NameTable);
			_mustBeTransformed = false;
		}
	
		
		public void sendAsXML()
		{
			_mustBeTransformed = false;
		}
		
		//
		// XPath methods
		//
		
		public XPathNodeIterator Select(string expression)
		{
			return _navigator.Select(expression);
		}
		
		public string GetValueOf(string expression)
		{
			XPathNodeIterator i = _navigator.Select(expression);
			
			if(i.MoveNext()) {
				return i.Current.Value;				
			} else {
				return "";
			}
		}

		public XPathNodeIterator SelectNS(string expression)
		{
			return _navigator.Select(expression, _namespaces);
		}
		
		public string GetValueOfNS(string expression)
		{
			XPathNodeIterator i = _navigator.Select(expression, _namespaces);
			
			if(i.MoveNext()) {
				return i.Current.Value;				
			} else {
				return "";
			}
		}
		
		public bool GetValueOfExp(string expression)
		{
			XPathNodeIterator i = _navigator.Select(expression);
			
			if(i.MoveNext()) {
				return (("1" == i.Current.Value) ? true : false);
			} else {
				return false;
			}
		}

		public string GetInnerOf(string expression)
		{
			string s = "";
			XPathNodeIterator i = _navigator.Select(expression);
			
			while(i.MoveNext()) s += i.Current.InnerXml;
			return s;
		}

		//
		// Processing method
		//
		
		public void processToStream(TextWriter output)
		{			
			string xslFile = Manager.i.config.
				GetValueOf("//Configuration/Views/View[@name='" + _xslName + "']");
			
			Manager.i.info("XML", InnerXml);
			
			XslTransform transform = new XslTransform();
			try {
				transform.Load(xslFile);
				transform.Transform(DocumentElement.CreateNavigator(), null, output, null);
			} catch(Exception e) {
				Manager.i.error("Document", e);
			}									
		}
		
		//
		// Additional service
		//
		
		public void setPrefix(string p)
		{
		   string inner = DocumentElement.InnerXml;
		   
		   InnerXml = "<" + p + "document timestamp='" + DateTime.Now.ToString() + "'>" + inner + "</" + p + "document>";
			_navigator = DocumentElement.CreateNavigator();
		}
		
		public void addNamespace(string name, string url)
		{
			_namespaces.AddNamespace(name, url);
		}
	}
}
